package com.panopset.gui;

import java.awt.Color;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

import com.panopset.Strings;
import com.panopset.swing.App;
import com.panopset.swing.FontManager;
import com.panopset.swing.FontManager.FontType;

/**
 * Validating Text Field. Background red if invalid, yellow if blank.
 * 
 * @author Karl Dinwiddie
 * 
 */
public abstract class ValidatingField<T> {

	/**
	 * Name of field.
	 */
	private final String name;

	/**
	 * 
	 * @param name
	 *            Name of field, used in alerts when not valid.
	 */
	public ValidatingField(final String name) {
		this.name = name;

		FontManager.register(tf, FontType.monospace);

		tf.addKeyListener(new KeyAdapter() {

			@Override
			public void keyReleased(final KeyEvent e) {
				ValidatingField.this.updateGui();
			}
		});

		tf.addFocusListener(new FocusAdapter() {

			@Override
			public void focusLost(final FocusEvent e) {
				ValidatingField.this.save();
			}
		});
		updateGui();
	}

	public final String getName() {
		return name;
	}

	/**
	 * @return Text value.
	 */
	public abstract T getValue() throws Exception;

	/**
	 * Set value.
	 * 
	 * @param val
	 *            Value to set.
	 */
	public void setValue(final String val) {
		tf.setText(val);
		tf.invalidate();
		updateGui();
		App.app.f.getFrame().validate();
	}

	/**
	 * Text field.
	 */
	private final TTextField tf = new TTextField() {

		@Override
	    public void setEnabled(final boolean enabled) {
	    	super.setEnabled(enabled);
	    	updateGui();
	    }
	};

	/**
	 * @return TTextField.
	 */
	public final TTextField getTf() {
		return tf;
	}

	/**
	 * Validate field.
	 * 
	 * @param s
	 *            Value to validate.
	 * @return true iff valid.
	 */
	public abstract boolean validate(final String s);

	/**
	 * Focus lost, save value somewhere.
	 */
	public abstract void save();

	/**
	 * Update.
	 */
	public String updateGui() {
		String s = tf.getText();
		if (!tf.isEnabled()) {
			tf.setBackground(Color.WHITE);
			return s;
		}
		if (Strings.isPopulated(s)) {
			if (validate(s)) {
				tf.setBackground(Color.WHITE);
			} else {
				tf.setBackground(Color.RED);
			}
		} else {
			tf.setBackground(Color.YELLOW);
		}
		return s;
	}
}
